/*
*
*
*     文档创建：jjl, jjl@hzncc.com
*/

#include <Vrmii_connector.h>	//测试模块rmii_connector
#include <verilated.h>

#include <verilated_vcd_c.h>

//创建一个测试模板
template<class MODULE>	class TESTBENCH {
public:
	unsigned long	m_tickcount;
	//模块实例化
	MODULE	*m_core;
	//生成波形文件的VerilatedVcdC对象指针
	VerilatedVcdC *tfp;

public:
	//模板构造函数
	TESTBENCH(void) {
		m_core = new MODULE;
		tfp = new VerilatedVcdC ;
		m_tickcount = 0l;
		//开启存储波形文件
		m_core->trace(tfp, 99);
		tfp->open("wave_dbg.vcd");

		//对仿真的输入进行初始化
		m_core->sys_clk 		= 0;
	}
	
	//模板的析构函数
	virtual ~TESTBENCH(void) {
		tfp->close();
		delete m_core;
		delete tfp;
		m_core = NULL;
	}

	virtual void reset(void) {	
		//调用模块的复位引脚
		m_core->sys_reset_n = 0;
		this->tick();
		m_core->sys_reset_n = 1;
		this->tick();
		//在此行复位结束
        
	}

	virtual void tick(void) {
		m_core->sys_clk = 0;
		m_core->eval();
		//计算组合逻辑
		tfp->dump(m_tickcount++); 
		
		// 上升沿，计算时序逻辑的值
		m_core->sys_clk = 1;
		m_core->eval();
		tfp->dump(m_tickcount++);
		// 下降沿，计算组合逻辑的值
		//m_core->sys_clk = 0;
		//m_core->eval();

	}

	virtual bool done(void) { return (Verilated::gotFinish()); }

    //对phy0 进行输入
    void phy0_rx_gen(){
        int i;
        m_core->phy0_rxdv = 1;
        for(i=0; i < 65; i++){
            
            if(i<32)
                m_core->phy0_rxd = 1;   //2'b01
            else if(i==32)
                m_core->phy0_rxd = 3;   //2'b11
            else if(i<61)
                m_core->phy0_rxd = random() & 0x03;
            else {
                m_core->phy0_rxdv = m_core->phy0_rxdv ? 0:1;
                m_core->phy0_rxd = random() & 0x03;
            }
            //短路 rxdv和txen
            m_core->txen = m_core->rxdv;
            m_core->txd = m_core->rxd;
            this->tick();   
        }
        m_core->phy0_rxdv = 0;
        this->tick();   
    }
    void phy1_rx_gen(){
        int i;
        m_core->phy1_rxdv = 1;
        for(i=0; i < 65; i++){
            
            if(i<32)
                m_core->phy1_rxd = 1;   //2'b01
            else if(i==32)
                m_core->phy1_rxd = 3;   //2'b11
            else if(i<61)
                m_core->phy1_rxd = random() & 0x03;
            else {
                m_core->phy1_rxdv = m_core->phy1_rxdv ? 0:1;
                m_core->phy1_rxd = random() & 0x03;
            }
            this->tick();   
        }
        m_core->phy1_rxdv = 0;
        this->tick();   
    }

};



int main(int argc, char **argv) {
	int i;
	Verilated::commandArgs(argc, argv);

	//初始化调试模块
	Verilated::traceEverOn(true);

	TESTBENCH<Vrmii_connector> *tp = new TESTBENCH<Vrmii_connector>();
	printf("Run sim...\n");

	tp->reset();


	// 运行20个clk
	for(i=0; i< 20; i++){
        tp->phy0_rx_gen();
        tp->tick();
    }

	for(i=0; i< 20; i++){
        tp->phy1_rx_gen();
        tp->tick();
    }
    if(Verilated::gotFinish())
	    exit(0);


	
	tp->done();
	printf("Run finish ... \n");
	//exit(EXIT_SUCCESS);
	return 0;
}


